import React, {
  createContext,
  useContext,
  ReactNode,
  useEffect,
  useState,
  useMemo,
} from 'react';
import {SolanaTokenMetadata} from '../../types';

export type SolanaTokenListContextType = {
  solanaTokenList: Array<SolanaTokenMetadata>;
  setSolanaTokenList: (solanaTokenList: Array<SolanaTokenMetadata>) => void;
};

export const SolanaTokenListContext = createContext<
  SolanaTokenListContextType | undefined
>(undefined);

export const useSolanaTokenListProvider = (): SolanaTokenListContextType => {
  const context = useContext(SolanaTokenListContext);
  if (!context) {
    throw new Error(
      'useSolanaTokenListProvider must be used within an SolanaTokenListProvider',
    );
  }
  return context;
};

export function SolanaTokenListProvider({
  children,
}: Readonly<{
  children: ReactNode;
}>) {
  const [solanaTokenList, setSolanaTokenList] = useState<SolanaTokenMetadata[]>(
    [],
  );
  const fetchSolanaTokenList = async () => {
    const resposne = await fetch(
      'https://raw.githubusercontent.com/solana-labs/token-list/refs/heads/main/src/tokens/solana.tokenlist.json',
      {
        method: 'GET',
      },
    );

    if (resposne.status == 200) {
      const data = await resposne.json();
      const tokens =
        typeof data['tokens'] !== 'undefined' ? data['tokens'] : [];
      const tmpSolanaTokenList: Array<SolanaTokenMetadata> = [];
      for (let i = 0; i < tokens.length; i++) {
        const token = tokens[i];
        const chainId = Number(token['chainId']);
        let wrappedChainId: string = '';
        switch (chainId) {
          case 101:
            wrappedChainId = 'solana-mainnet';
            break;
          case 102:
            wrappedChainId = 'solana-testnet';
            break;
          case 103:
            wrappedChainId = 'solana-devnet';
            break;
          default:
            wrappedChainId = 'solana-devnet';
        }
        const tmpSolanaToken: SolanaTokenMetadata = {
          chainId: chainId,
          wrappedChainId: wrappedChainId,
          address: token['address'],
          symbol: token['symbol'],
          name: token['name'],
          decimals: Number(token['decimals']),
          logoURI: token['logoURI'],
        };
        tmpSolanaTokenList.push(tmpSolanaToken);
      }
      setSolanaTokenList(tmpSolanaTokenList);
    }
  };

  useEffect(() => {
    if (solanaTokenList.length == 0) {
      fetchSolanaTokenList();
    }
  }, [solanaTokenList, setSolanaTokenList]);

  const value = useMemo(
    () => ({
      solanaTokenList,
      setSolanaTokenList,
    }),
    [solanaTokenList, setSolanaTokenList],
  );

  return (
    <SolanaTokenListContext.Provider value={value}>
      {children}
    </SolanaTokenListContext.Provider>
  );
}
